package com.app.system.config.requestLimit;

import com.app.system.utils.WebUtils;
import com.app.system.utils.exception.RequestLimitException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by WCF on 2019/9/4.
 */
@Aspect
@Component
@SuppressWarnings("all")
public class RequestLimitContract {

    //用于存储记录
    private Map<String, Integer> redisTemplate = new HashMap<String, Integer>();

    /**
     * 系统权限过滤
     */
//    @Pointcut(value = "execution(* com.app.system.permission.web.permission.*.*(..))")
//    public void reqSystem() {
//    }
//
//    /**
//     * 业务日志过滤
//     */
//    @Pointcut("execution(* com.app.business.web..*(..))")
//    public void reqBusiness() {
//    }
    @Pointcut(value = "bean(*Controller)")
    private void requestLimit() {

    }


    @Before(value = "requestLimit() && @annotation(limit)")
    public void requestLimit(final JoinPoint joinPoint, RequestLimit limit) throws RequestLimitException {
        try {
            //获取 HttpServletRequest 参数
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            if (request == null) {
//                logger.error("方法中缺失HttpServletRequest参数");
//                throw new HttpServletException("方法中缺失HttpServletRequest参数");
            }

            String ip = WebUtils.getIpAddr(request);
            String url = request.getRequestURL().toString();
            final String key = "req_limit_".concat(url).concat(ip);

//            System.out.println("ip = " + ip + "\n" + " url = " + url + "\n" + " key = " + key);

            if (redisTemplate.get(key) == null || redisTemplate.get(key) == 0) {
                redisTemplate.put(key, 1);
            } else {
                redisTemplate.put(key, redisTemplate.get(key) + 1);
            }
            int count = redisTemplate.get(key);
//            System.out.println("count====" + count);
            if (count > 0 && count == 1) {
                Timer timer = new Timer();
                TimerTask task = new TimerTask() {    //创建一个新的计时器任务。
                    @Override
                    public void run() {
//                        System.out.println("=========run");
                        if (!key.equals("")) {
                            redisTemplate.remove(key);
                        }
                    }
                };
                timer.schedule(task, limit.time());
                //安排在指定延迟后执行指定的任务。task : 所要安排的任务。limit.time() : 执行任务前的延迟时间，单位是毫秒。
            }
            if (count > limit.count()) {
//                logger.info("用户IP[" + ip + "]访问地址[" + url + "]超过了限定的次数[" + limit.count() + "]");
                throw new RequestLimitException();
            }
        } catch (RequestLimitException e) {
            throw e;
        } catch (Exception e) {
//            logger.error("发生异常: ", e);
        }
    }
}
